package com.imessage.utils;

import com.application.BeanContext;
import com.imessage.comm.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.File;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class PackageUtil {
    /**
     * 返回包下所有的类
     * @param packagePath 包名
     * @return List<String> 包下所有的类
     * @throws URISyntaxException
     * */
    public static  List<String> getPackageClasses(String packagePath) {

        return getPackageClasses(packagePath,false);
    }
    /**
     * 返回包下所有的类
     * @param packagePath 包名全路径
     * @param classWithPath 返回全路径开关 true 自动带上包名
     * @return List<String> 包下所有的类
     * @throws URISyntaxException
     * */
    public static  List<String> getPackageClasses(String packagePath,boolean classWithPath) {
        Environment environment = BeanContext.getApplicationContext().getEnvironment();
        List<String> classNames = getClassName(environment,packagePath);
        List<String>result =new ArrayList<String>(classNames.size());
        String path =classWithPath?packagePath+".":"";
        for (String className : classNames) {
            result.add(path+className.substring(className.lastIndexOf(".")+1));
        }
        return result;
    }



    private static List<String> getClassName(Environment environment,String packageName)  {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String path=StrUtil.getOsResourceLoc(environment);


        try{
            /**
             * 项目变更或手动创建文件后，导致文件与项目最新的枚举文件不一致，会导致项目出错。
             * 所以，每次启动项目后将该文件夹的所有文件删除，重新生成最新的项目枚举文件。
             */
            File file = new File(path);
            if(!file.exists()) {
                file.mkdir();
            }
            String filePath =path +File.separator+Constants.PROJECT_NAME ;
            file = new File(filePath);
            if(!file.exists()) {
                file.mkdir();
            }
            filePath =path +File.separator+Constants.PROJECT_NAME+File.separator+"type";
            file = new File(filePath);
            if(!file.exists()) {
                file.mkdir();
            }
            String targetFilePath =path +File.separator+Constants.PROJECT_NAME+File.separator+"type";
            File ttfFile = new File(targetFilePath);
            if(!ttfFile.exists()) {
                ttfFile.mkdir();
            }else{
                File[] fileList=ttfFile.listFiles();
                for(File f:fileList){
                    f.delete();
                }
            }
        }catch (Exception e){
            log.error("", e);
        }
        try{
            Resource[] resources = resolver.getResources(packageName.replace(".", "/")+"/*.*");
            for(Resource resource : resources) {
                InputStream stream = resource.getInputStream();
                String targetFilePath =path +File.separator+Constants.PROJECT_NAME+File.separator+"type"+
                        File.separator+resource.getFilename();
                File ttfFile = new File(targetFilePath);
                if(!ttfFile.getParentFile().exists()) {
                    ttfFile.getParentFile().mkdir();
                }
                FileUtils.copyInputStreamToFile(stream, ttfFile);
            }
        }catch (Exception e){
            log.error("", e);
        }
        List<String> fileNames = getClassName(path+File.separator+Constants.PROJECT_NAME+File.separator+"type", null);
        return fileNames;
    }

    private static List<String> getClassName(String filePath, List<String> className) {
        List<String> myClassName = new ArrayList<String>();
        File file = new File(filePath);
        File[] childFiles = file.listFiles();
        for (File childFile : childFiles) {
            if (childFile.isDirectory()) {
                myClassName.addAll(getClassName(childFile.getPath(), myClassName));
            } else {
                String childFilePath = childFile.getPath();
                childFilePath = childFilePath.substring(childFilePath.indexOf("\\classes") + 9, childFilePath.lastIndexOf("."));
                childFilePath = childFilePath.replace("/", ".");
                File f=new File(childFilePath);
                if(f.exists()){
                    myClassName.add(childFilePath);
                }else{
                    childFilePath = childFilePath.replace("\\", ".");
                    myClassName.add(childFilePath);
                }
            }
        }

        return myClassName;
    }
}